package com.zz.framework.core.base

import android.content.Context
import android.text.TextUtils
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import com.zz.framework.core.annotation.BindViewModel
import com.zz.framework.core.common.ViewModelFactory
import com.zz.framework.core.ext.showToast
import java.lang.reflect.Field

/**
 * Copyright © 2019 zanezhao All rights reserved.
 * Created by zanezhao on 2019-11-11 11:29.
 * @author: zanezhao 1820022519@qq.com
 * @version: V1.0
 */
abstract class BaseViewModelFragment(useBinding: Boolean = false) : BaseImmersionBarFragment(), LifecycleObserver {
    private lateinit var viewModel: BaseViewModel<*>
    private val _useBinding = useBinding
    protected lateinit var mBinding: ViewDataBinding

    override fun onAttach(context: Context) {
        super.onAttach(context)
        //默认注册ViewModel
        initViewModel()
    }


//    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//        return if (_useBinding) {
//            mBinding = DataBindingUtil.inflate(inflater,getLayoutResId(),container,false)
//            mBinding.root
//        } else
//            inflater.inflate(getLayoutResId(), container, false)
//    }


    /**
     *  根据 @BindViewModel 注解, 查找注解标示的变量（ViewModel）
     *  并且 创建 ViewModel 实例, 注入到变量中
     */
    private fun initViewModel() {
        javaClass.fields
            .filter { it.isAnnotationPresent(BindViewModel::class.java) }
            .forEach {
                it?.apply {
                    isAccessible = true
                    var annotation = this.getAnnotation(BindViewModel::class.java)
                    set(
                        this@BaseViewModelFragment,
                        getViewModel(annotation.isSingle, annotation.isRegisterError, this)
                    )
                }
            }

    }

    @Suppress("UNCHECKED_CAST")
    private fun getViewModel(isSingle: Boolean, isRegisterError: Boolean, field: Field): ViewModel {
//        var viewModelName: String? = field.genericType.typeName
        var viewModelName: String? = null
        if (viewModelName == null) {
            viewModelName = this.javaClass.getCanonicalName()
        }
        if (isSingle) viewModelName = "${this.javaClass.canonicalName}${this.toString()} :$viewModelName" else viewModelName
        val mViewModel: BaseViewModel<*> =
            ViewModelFactory.createViewModel(requireActivity(), viewModelName, field,isSingle)
        if (isRegisterError) {
            observeErrorLiveData(mViewModel)
        }
        observeFinishLiveData(mViewModel)
        viewModel = mViewModel
        return mViewModel
    }

    protected fun observeErrorLiveData(viewModel: BaseViewModel<*>) {
        viewModel?.errorLiveData?.observe(
            this,
            Observer { it?.let { error(it.code, it.message) } })
    }

    protected fun observeFinishLiveData(viewModel: BaseViewModel<*>) {
        viewModel?.finishedLiveData?.observe(
            this,
            Observer { it?.let {
                dismissProgress()
            }})
    }

    override fun onDestroyView() {
        removeViewModelObserver()
        super.onDestroyView()
    }

    private fun removeViewModelObserver() {
        if (this::viewModel.isInitialized) {
            viewModel?.let {
                lifecycle.removeObserver(it)
            }
        }
    }

    override fun initData() {
        initObserver()
    }

    open fun initObserver(){

    }

    open fun error(code: Int, message: String) {
        dismissProgress()
        error(message)
    }

    open fun error(message: String) {
        if (TextUtils.equals(message,"closed")){
            return
        }
//        activity?.createErrorDialog(message)?.show()
        activity?.showToast(message)
    }
}